/**
 * 
 * 上海金扳手信息科技股份有限公司
 * Copyright (c) 1991-2018 Jinbanshou,Inc.All Rights Reserved.
 */
package com.frames.newtable;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.frames.table.T2BDao;
import com.frames.table.T2BVO;
import com.utils.bean.BeanUtil;
import com.utils.validate.Detect;

/**
    * @ClassName: PojoFromTable
    * @Description: 创建单表业务，自动生成表的实体类、增删改查接口和实现mappper
    * @author likai
    * @date 2017年4月9日
    *
    */
@Deprecated
public class TableMapperUtil{
	public static Logger log = LoggerFactory.getLogger(TableMapperUtil.class);
	private T2BDao t2bDao;
	private TableConfig tableConfig;
	private static TableMapperUtil tableMapperUtil;
	@SuppressWarnings("resource")
	private TableMapperUtil(TableConfig config,String springPath) {
		super();
		ApplicationContext ctx = new ClassPathXmlApplicationContext(springPath);  
		t2bDao= (T2BDao)ctx.getBean("t2BDao");  
		this.tableConfig=config;
	}
	
	public static TableMapperUtil init(TableConfig config,String springPath) {
		if (tableMapperUtil==null) {
			return new TableMapperUtil(config,springPath);
		}
		return tableMapperUtil;
	}
	/*  
	    * @Description:生成pojo、mapper.xml、module接口的入口
	    * 
	    */
	public  void convertTableToPojoAndMapper() {
		T2BVO vo = new T2BVO();
		vo.setPrefix(tableConfig.tablePrefix());//tablePrefix为要刷选出的表的前缀,""为全部表
		vo.setDbname(tableConfig.dbName());
		List<T2BVO> tables = t2bDao.listTables(vo);
		log.info("---------创建开始-----------");
		for (T2BVO t2b : tables) {
			String table=t2b.getTableName();
			String tableComment=t2b.getTableComment();
			vo.setTableName(table);
			List<T2BVO> cols = t2bDao.listTableCols(vo);
			String className="";
			String prefix=tableConfig.tablePrefix();//去除前缀
			if (tableConfig.reomvePrefix()) {				
				if (table.toUpperCase().startsWith(prefix.toUpperCase())) {					
					className = table.substring(prefix.length());
				}else {
					className=table;
				}
			}else {
				className=table;
			}

			className = BeanUtil.columnToField2(className);
			//生成table对应的实体类pojo				
			createPojo(table,tableComment,className, cols);
			if (tableConfig.createModuleAndXml()) {
				//生成table对应的增删改查mapper	
				if (tableConfig.useSplitTable()) {
					//生成包含动态数据源，分表策略和缓存策略的module和xml
					createMapperClass(table,className,cols);
				}else {
					//生成只包含缓存策略的module和xml
					createSimpleMapperClass(table,className,cols);			
				}
			}					
		} 
		log.info("---------创建结束-----------");
		
	}
	
	/*  
	    * @Description:生成mapper.xml和mapper接口的入口（简单模式，不包含动态数据源切换）
	    * 
	    * @param:													是否必须
	    * 
	    * tableName:表名													是
	    * className:生成的类名												是
	    * cols:表所有的列信息													是
	    */
	private  void createSimpleMapperClass(String table,String className,  List<T2BVO> cols) {
		String moduleSuffix= BeanUtil.columnToField2(tableConfig.moduleSuffix().toLowerCase());
		
		String moduleClassName ="T"+className+moduleSuffix ;//接口名
		String modulePackagePath =tableConfig.modulePackagePath()+"."+moduleClassName;//接口所在包		
		String moduleFilePath =tableConfig.moduleFilePath()+"/"+ moduleClassName+ ".java";//生成接口文件地址
		String mapperXmlFilePath =tableConfig.mapperXmlFilePath()+"/"+ moduleClassName+"Mapper.xml";//生成xml文件地址		
		File moduleFile = new File(moduleFilePath);
		File mapperXmlFile = new File(mapperXmlFilePath);
		
		if (!moduleFile.exists()) {// 如果存在，则不重建
			//生成接口
			createSimpleModule(table,className,moduleClassName,tableConfig.modulePackagePath(),moduleFile);
		}
		if (!mapperXmlFile.exists()) {// 如果存在，则不重建
			//生成接口实现xml
			createmSimpleMysqlMapperXml(table,className,modulePackagePath,mapperXmlFile,cols);
		}
	}
	
	
	/*  
	    * @Description:生成pojo实现方法
	    * 
	    * @param:													是否必须
	    * 
	    * tableName:表名													是
	    * className:生成的类名												是
	    * cols:表所有的列信息													是
	    */
	private  void createPojo(String tableName,String tableComment,String className,List<T2BVO> cols) {		
		if (!Detect.notEmpty(tableConfig.pojoFilePath())||!Detect.notEmpty(tableConfig.pojoPackagePath())) {
			return;
		}
		String filePath= tableConfig.pojoFilePath().replace(".", "/");
		String packagePath= tableConfig.pojoPackagePath().replace("/", ".");
		String classPath =filePath+"/"+ className + ".java";//生成java文件路径
		File classFile = new File(classPath);
		String userPageHelp="		orderLimit=setOrderCols(table,unuse);\n";//是否分页
		if (tableConfig.usePageHelp()) {
			//启用分页
			userPageHelp="		orderLimit=setOrderCols(table,unuse)+setLimit();\n";
		}
		if (!classFile.exists()) {
			// 如果不存在，则创建
			try {
				classFile.createNewFile();
				StringBuilder sbImport = new StringBuilder();
				StringBuilder sb = new StringBuilder();
				sbImport.append("package " + packagePath + ";\n\n");
				
				sbImport.append("import java.util.Map;\n");
				sbImport.append("import org.apache.commons.lang3.ArrayUtils;\n");
				sbImport.append("import com.utils.transtype.TransType;\n");
				sbImport.append("import com.supers.pojo.Table;\n");
				sbImport.append("import com.supers.enums.TableSort;\n");
				sbImport.append("import com.utils.string.StringUtil;\n");
				sbImport.append("import com.fasterxml.jackson.annotation.JsonInclude;\n");
				sb.append("@JsonInclude(JsonInclude.Include.NON_DEFAULT)\n");
				sb.append("public class " + className + " extends Table{\n\n");
				//属性			
				sb.append("	public String table=\""+ tableName + "\";//"+tableComment+"\n");
				
				String id="";
				String colsAndWhere="\"{";
				String clowns="\"{";
				String clown1="\" ";
				for (T2BVO vo : cols) {
					String colKey = vo.getColKey();
					String type = vo.getColType().toLowerCase();
					String col = vo.getColName();
					String clown=BeanUtil.columnToField(col);
					colsAndWhere+="'"+clown+"':{'col':'"+col+"','operate':'='},";
					clown1+="TBL."+col+",";
					clowns+="'"+clown+"':'"+col+"',";
					if (colKey.equalsIgnoreCase("PRI")) {
						id=col;
						if (type.contains("bigint")) {
							sb.append("	public Long returnId;//插入数据返回ID\n");
						}else if (type.contains("int")) {
							if (type.contains("unsigned")) {	
								sb.append("	public Long returnId;//插入数据返回ID\n");
							}else {							
								sb.append("	public Integer returnId;//插入数据返回ID\n");
							}
						}
					}
					
				}
				sb.append("	public String primaryKey=\""+ id + "\";//表的主键\n");

				colsAndWhere=colsAndWhere.substring(0,colsAndWhere.length()-1)+"}\"";
				clowns=clowns.substring(0,clowns.length()-1)+"}\"";
				clown1=clown1.substring(0,clown1.length()-1)+" \"";
				sb.append("	//获取排序和where条件使用,operate为运算符:=、<、<=、>、>=、!=、in范围、lt%左模糊匹配、rt%右模糊匹配、%%全模糊匹配、not非空、null空\n");
				sb.append("	public String columns="+ clowns + ";\n");
				sb.append("	public String colsAndWhere="+ colsAndWhere + ";\n");
				sb.append("	//select选择列\n");
				sb.append("	public static String selectColumn1="+ clown1 + ";\n");
				
				String dateImport="";
				String decimalImport="";
				String lengthImport="";
				String notNullImport="";
				boolean hasLong=false;
				for (T2BVO vo : cols) {
					String col = vo.getColName();
					String clown=BeanUtil.columnToField(col);
					String type = vo.getColType().toLowerCase();
					String javaType="";
					if (type.contains("bigint")) {
						hasLong=true;
						sb.append("	@JsonSerialize(using = ToStringSerializer.class)\n");	
						javaType = " Long ";
					}else if (type.contains("int")) {
						if (type.contains("unsigned")) {	
							sb.append("	@JsonSerialize(using = ToStringSerializer.class)\n");							
							javaType = " Long ";
						}else {							
							javaType = " Integer ";
						}
					}else if (type.contains("date")||type.contains("year")||type.contains("time")||type.contains("timestamp")||type.contains("datetime")) {
						javaType = " Date ";
						dateImport="import java.util.Date;\n";
					}else if (type.contains("double")) {
						javaType = " Double ";
					}else if (type.contains("decimal")) {
						javaType = " BigDecimal ";
						decimalImport="import java.math.BigDecimal;\n";
					}else if (type.contains("float")) {
						javaType = " Float ";
					}else {
						javaType = " String ";
						lengthImport="import org.hibernate.validator.constraints.Length;\n";
					}
					sb.append("	private" + javaType + clown + ";");
					sb.append("//" + vo.getColComment() + "\n");
				}
				if (hasLong) {
					sbImport.append("import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;\n");
					sbImport.append("import com.fasterxml.jackson.databind.annotation.JsonSerialize;\n");
				}
				sbImport.append(dateImport);
				sbImport.append(decimalImport);
				sbImport.append(lengthImport);
				sbImport.append("\n\n");
				sb.append("\n\n");
				
				//设置查询列
				sb.append("	//设置查询列\n");
				sb.append("	public  void setSelectCols(String table,String selectColumn) {\n");				
				sb.append("		if (table.equals(\"\")) {\n");
				sb.append("			selectColumn=selectColumn.replace(\"TBL.\", \"\");\n");
				sb.append("		}else{\n");
				sb.append("			selectColumn=selectColumn.replace(\"TBL\", table);\n");
				sb.append("		}\n");
				sb.append("		selectCols=selectColumn;\n");
				sb.append("	}\n");
				//设置排序和分页
				sb.append("	//设置排序和分页\n");
				sb.append("	public void setOrderLimit(String table,String unuse){\n");
				sb.append(userPageHelp);
				sb.append("	}\n\n");			
				
				
				//设置排序
				sb.append("	//设置排序\n");
				sb.append("	@SuppressWarnings(\"unchecked\")\n");
				sb.append("	private String setOrderCols(String table,String unuse){\n");
				sb.append("		String realOrder=\"\";\n");
				sb.append("		Map<String, String> clownsMap=TransType.jsonToObject(columns, Map.class);\n");
				sb.append("		String[] orders=StringUtil.split(this.order, \",\");\n");
				sb.append("		String[] sorts=StringUtil.split(this.sort, \",\");\n");
				sb.append("		int length=orders.length-sorts.length;\n");
				sb.append("		if (length>=0) {\n");
				sb.append("			sorts=ArrayUtils.addAll(sorts, new String[length]);\n");
				sb.append("			for (int i = 0; i < orders.length; i++) {\n");
				sb.append("				String clown=clownsMap.get(orders[i]);\n");
				sb.append("				if (clown!=null) {\n");
				sb.append("					realOrder+= (table!=\"\"?table+\".\":\"\")+clown+(this.sort!=\"\"?TableSort.getSort(sorts[i]):\"\")+\",\";\n");
				sb.append("				}\n");
				sb.append("			}\n");
				sb.append("			if (!realOrder.equals(\"\")) {\n");
				sb.append("				this.order=\"  ORDER BY \"+realOrder.substring(0,realOrder.length()-1);\n");
				sb.append("			}else {	\n");
				sb.append("				this.order = \"\";\n");
				sb.append("			}\n");	
				sb.append("			return order;\n");						
				sb.append("		}\n");	
				sb.append("		return \"\";\n");	
				sb.append("	}\n\n");	
				
				//设置分页
				if (tableConfig.usePageHelp()) {
					sb.append("	//设置分页\n");
					sb.append("	private String setLimit(){\n");
					sb.append("		String limit=\"\";\n");
					sb.append("		if (pageSize!=0) {\n");
					sb.append("			if (pageNum<1) {\n");
					sb.append("				pageNum=1;\n");
					sb.append("			}\n	");
					sb.append("			limit = \" LIMIT \"+(pageNum-1)*pageSize+\",\"+pageSize;\n");
					sb.append("		}\n");
					sb.append("		return limit;\n");
					sb.append("	}\n\n");
				}
	
				
				// setter & getter
				for (T2BVO vo : cols) {
					String col = vo.getColName();
					String type = vo.getColType().toLowerCase();
					String isNull = vo.getIsNull().toLowerCase();
					String javaType = " String ";
					if (type.contains("bigint")) {
						javaType = " Long ";
					}
					else if (type.contains("int")) {
						if (type.contains("unsigned")) {							
							javaType = " Long ";
						}else {							
							javaType = " Integer ";
						}
					}				 
					else if (type.contains("date")||type.contains("year")||type.contains("time")||type.contains("timestamp")||type.contains("datetime")) {
						javaType = " Date ";
					}
					else if (type.contains("double")) {
						javaType = " Double ";
					}else if (type.contains("decimal")) {
						javaType = " BigDecimal ";
					}
					else if (type.contains("float")) {
						javaType = " Float ";
					}
					String property = BeanUtil.columnToField(col);
					if (!id.equals(col)) {
						//非主键加验证注解
						if (isNull.equals("no")) {
							sb.append("	@NotNull(message=\""+property+"不能为空\")\n");
							notNullImport="import javax.validation.constraints.NotNull;\n";
						}
						if (javaType.equals(" String ")&&vo.getColMaxLength()!="0") {
							sb.append("	@Length(max="+vo.getColMaxLength()+",message=\""+property+"长度不能超过"+vo.getColMaxLength()+"\")\n");
						}
					}
					
					sb.append("	public" + javaType + "get" + BeanUtil.upperCaseFirst(property) + "(){\n");
					String priCol=BeanUtil.columnToField(id);//主键属性
					if (property.equals(priCol)) {
						sb.append("		if ("+priCol+"!=null) {\n");
						sb.append("			return "+priCol+";\n");
						sb.append("		}else {\n");
						sb.append("			return returnId;\n");
						sb.append("		}\n");
					}else {
						sb.append("		return " + property + ";\n");
					}
					sb.append("	}\n");

					sb.append("	public void set" + BeanUtil.upperCaseFirst(property) + "(" + javaType.trim() + " "
							+ property + "){\n");
					sb.append("		this." + property + " = " + property + ";\n");
					sb.append("	}\n\n");
				}
				
				//toString					
				sb.append("	@Override\n");
				sb.append("	public String toString(){\n");
				sb.append("		return \""+className +"[pageNum=\"+pageNum+\",pageSize=\"+pageSize+\",order=\"+order+\",sort=\"+sort+\n");
				sb.append("		\",");
				int i=1;
				for (T2BVO vo : cols) {
					String col = vo.getColName();
					String clown=BeanUtil.columnToField(col);				
					sb.append( clown+"=\"+"+clown+"+\""+(i!=cols.size()?",":""));
					if (i%5==0) {
						sb.append("\"\n");
						sb.append("		+\"");
					}
					i++;
				}
				sb.append("]\";\n");
				sb.append("	}\n\n");
						
				
				sbImport.append(notNullImport);
				sb.append("\n\n}\n\n");
				sbImport.append(sb);
				OutputStream os = new FileOutputStream(classFile);
				PrintStream ps = new PrintStream(os);
				ps.print(sbImport);

				os.flush();
				os.close();
				ps.flush();
				ps.close();

			}
			catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	
	
	
	//---------------------------------------------------不包含动态数据源切换模式的module和mapper.xml-------------------------------------------------------------------

	
	
	/*  
	    * @Description:生成module接口的实现方法（简单模式，不包含动态数据源切换）
	    * 
	    * @param:													是否必须
	    * 
	    * table:表名	（t_user）												是
	    * pojoClass:表的pojo对象名（User）													是
	    * className:接口名（UserModule）												是
	    * packagePath:接口包路径	（com.module）										是
	    * classFile:接口文件													是
	    */
	private  void createSimpleModule(String table,String pojoClass,String className,String packagePath,File classFile) {
		try {
			StringBuilder sb = new StringBuilder();
			StringBuilder sbImport = new StringBuilder();
			sbImport.append("package " + packagePath + ";\n\n");
			String updateCacheHandle="";
			String queryCacheHandle="";
			if (tableConfig.useCache()) {
				updateCacheHandle="	 @CacheHandle(handle=SqlType.UPDATE)\n";
				queryCacheHandle="	 @CacheHandle\n";
				sbImport.append("import com.supers.annotation.CacheHandle;\n");
				sbImport.append("import com.supers.enums.SqlType;\n");
			}
			String usePojo="";
			if (tableConfig.usePojo()) {
				usePojo=pojoClass;
				sbImport.append("import "+tableConfig.pojoPackagePath()+"."+pojoClass+";\n");
			}else {
				usePojo="Map<String, Object>";
				sbImport.append("import java.util.Map;\n");
			}
			String pojoName=BeanUtil.lowerCaseFirst(pojoClass);
			classFile.createNewFile();

			
			sbImport.append("import java.util.List;\n");
			sbImport.append("import org.apache.ibatis.annotations.Param;\n");
			sbImport.append("\n\n");
			sb.append("public interface " + className + "{\n\n");
			
			//属性表名
			sb.append("	 String table=\""+table+"\";\n\n");
						
			//增删改查方法
			sb.append(updateCacheHandle);
			sb.append("	 int add"+pojoClass+"(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//添加数据\n\n");
			sb.append(updateCacheHandle);
			sb.append("	 int batchAdd"+pojoClass+"(@Param(\""+pojoName+"s\")List<"+pojoClass+">"+" "+pojoName+"s);//批量添加数据\n\n");
			sb.append(updateCacheHandle);
			sb.append("	 int del"+pojoClass+"(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//删除数据\n\n");
			sb.append(updateCacheHandle);
			sb.append("	 int batchDel"+pojoClass+"ById(@Param(\"ids\")int[] ids);//根据id批量删除数据\n\n");
			sb.append(updateCacheHandle);
			sb.append("	 int update"+pojoClass+"ById(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//根据id修改数据\n\n");
			sb.append(updateCacheHandle);
			sb.append("	 int update"+pojoClass+"ByCondition(@Param(\"cols\")"+pojoClass+" "+pojoName+"Cols,@Param(\"condtions\")"+pojoClass+" "+pojoName+");//根据条件修改数据,cols需要修改的列，condtions条件\n\n");
			sb.append(updateCacheHandle);
			sb.append("	 int batchUpdate"+pojoClass+"ById(@Param(\""+pojoName+"s\")List<"+pojoClass+">"+" "+pojoName+"s);//根据id批量更新数据\n\n");
			sb.append(queryCacheHandle);
			sb.append("	 int get"+pojoClass+"Count(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//获取数据总数\n\n");
			sb.append(queryCacheHandle);
			sb.append("	 "+usePojo+" get"+pojoClass+"(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//获取一条数据\n\n");
			sb.append(queryCacheHandle);
			sb.append("	 List<"+usePojo+"> get"+pojoClass+"List(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//获取多条数据\n\n");
						
			sb.append("\n\n}\n\n");
			sbImport.append(sb);
			OutputStream os = new FileOutputStream(classFile);
			PrintStream ps = new PrintStream(os);
			ps.print(sbImport);
			os.flush();
			os.close();
			ps.flush();
			ps.close();
		}catch (IOException e) {
			e.printStackTrace();
		}

	}
	/*  
	    * @Description:生成mapper.xml的实现方法（mysql数据库）（简单模式，不包含动态数据源切换）
	    * 
	    * @param:													是否必须
	    * 
	    * table:表名	（t_user）												是
	    * pojoClass:表的pojo对象名（User）													是
	    * mapperClassPackage:映射的接口包路径（com.module）												是
	    * classFile:xml文件										是
	    * cols:表的所有列													是
	    */
	private  void createmSimpleMysqlMapperXml(String table,String pojoClass,String mapperClassPackage,File classFile,List<T2BVO> cols) {
		try {
			classFile.createNewFile();
			String pojoName=BeanUtil.lowerCaseFirst(pojoClass);
			StringBuilder sb = new StringBuilder();
			sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
			sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
			sb.append("<mapper namespace=\""+mapperClassPackage+"\" >\n\n");
			String id="";//表主键
			String pojoId="";//pojo对象的主键
			String usePojo="";
			if (tableConfig.usePojo()) {
				usePojo=tableConfig.pojoPackagePath().replace("/", ".")+"."+pojoClass;;
			}else {
				usePojo="map";
			}
			for (T2BVO vo : cols) {
				String colKey = vo.getColKey();
				String colName =vo.getColName();//表列名
				if (colKey.equalsIgnoreCase("PRI")) {
					id=colName;
					pojoId=BeanUtil.columnToField(id.toLowerCase());
					break;
				}
				
			}			

			sb.append("	<!-- 添加数据 -->\n");
			sb.append("	<insert id=\"add"+pojoClass+"\"  useGeneratedKeys=\"true\" keyProperty=\""+pojoName+"."+pojoId+"\">\n");
			sb.append("		INSERT INTO "+table+" (\n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColByParam("+pojoName+")}\n");
			sb.append("		) VALUES(\n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getValByParam("+pojoName+",'"+pojoName+"')}\n");
			sb.append("		) ON DUPLICATE KEY UPDATE update_date=#{"+pojoName+".createDate}\n");
			sb.append("	</insert> \n\n");
			
			sb.append("	<!-- 批量添加数据 -->\n");
			sb.append("	<insert id=\"batchAdd"+pojoClass+"\">\n");
			sb.append("		<foreach collection=\""+pojoName+"s\" index=\"index\" item=\"item\"  separator=\";\">\n  ");
			sb.append("		INSERT INTO "+table+" (\n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColByParam(item)}\n");
			sb.append("		) VALUES(\n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getValByParam(item,'item')}\n");
			sb.append("		) ON DUPLICATE KEY UPDATE update_date=#{item.createDate}\n");
			sb.append("		</foreach>\n");
			sb.append("	</insert> \n\n");
			
			sb.append("	<!-- 删除数据 -->\n");
			sb.append("	<delete id=\"del"+pojoClass+"\" >\n");
			sb.append("		delete from "+table+"  \n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam("+pojoName+",'"+pojoName+"')}\n");
			sb.append("	</delete>  \n\n");
			

			sb.append("	<!-- 根据id批量删除数据 -->\n");
			sb.append("	<delete id=\"batchDel"+pojoClass+"ById\" >\n");
			sb.append("		delete from "+table+" where "+id+" in \n");			
			sb.append("		<foreach collection=\"ids\" index=\"index\" item=\"item\" open=\"(\" close=\")\" separator=\",\">\n  ");
			sb.append("			#{item}\n");
			sb.append("		</foreach>\n");
			sb.append("	</delete>  \n\n");
			
			sb.append("	<!-- 根据id修改数据-->\n");
			sb.append("	<update id=\"update"+pojoClass+"ById\"  >\n");
			sb.append("		update "+table+" set  \n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColVal("+pojoName+",'"+pojoName+"','"+pojoId+"')}\n");
			sb.append("		where "+id+"=#{"+pojoName+"."+pojoId+"} \n");
			sb.append("	</update>  \n\n");
			
			sb.append("	<!-- 根据条件修改数据,cols需要修改的列，condtions条件-->\n");
			sb.append("	<update id=\"update"+pojoClass+"ByCondition\"  >\n");
			sb.append("		update "+table+" set  \n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColVal(cols,'cols','')}\n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam(condtions,'condtions')}\n");
			sb.append("	</update>  \n\n");
			
			sb.append("	<!-- 根据id批量更新数据-->\n");
			sb.append("	<update id=\"batchUpdate"+pojoClass+"ById\">\n");
			sb.append("		<foreach collection=\""+pojoName+"s\" index=\"index\" item=\"item\"  separator=\";\">\n  ");
			sb.append("		update "+table+" set  \n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColVal(item,'item','"+pojoId+"')}\n");
			sb.append("		where "+id+"=#{item."+pojoId+"} \n");
			sb.append("		</foreach>\n");
			sb.append("	</update> \n\n");
			
			sb.append("	<!-- 获取数据总数-->\n");
			sb.append("	<select id=\"get"+pojoClass+"Count\" resultType=\"int\">\n");
			sb.append("		SELECT count(1) FROM "+table+" \n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam("+pojoName+",'"+pojoName+"')}\n");
			sb.append("	</select>  \n\n");
			
			sb.append("	<!-- 获取一条数据-->\n");
			sb.append("	<select id=\"get"+pojoClass+"\" resultType=\""+usePojo+"\">\n");
			sb.append("		SELECT ${"+pojoName+".selectCols} FROM "+table+" \n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam("+pojoName+",'"+pojoName+"')} ${"+pojoName+".lock}\n");
			sb.append("	</select>  \n\n");
			
			sb.append("	<!-- 获取多条数据-->\n");
			sb.append("	<select id=\"get"+pojoClass+"List\"  resultType=\""+usePojo+"\">\n");
			sb.append("		SELECT ${"+pojoName+".selectCols} FROM "+table+" \n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam("+pojoName+",'"+pojoName+"')}\n");
			sb.append("		${"+pojoName+".orderLimit} \n");
			sb.append("	</select>  \n\n");
			

			
			sb.append("</mapper>");
			OutputStream os = new FileOutputStream(classFile);
			PrintStream ps = new PrintStream(os);
			ps.print(sb);
			os.flush();
			os.close();
			ps.flush();
			ps.close();
		}catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	
	//---------------------------------------------------包含动态数据源切换模式的module和mapper.xml-------------------------------------------------------------------

	/*  
	    * @Description:生成mapper.xml和mapper接口的入口（复杂模式，包含动态数据源切换）
	    * 
	    * @param:													是否必须
	    * 
	    * tableName:表名													是
	    * className:生成的类名												是
	    * cols:表所有的列信息													是
	    */
	private  void createMapperClass(String table,String className,  List<T2BVO> cols) {
		String moduleSuffix= BeanUtil.columnToField2(tableConfig.moduleSuffix().toLowerCase());
		
		String moduleClassName ="T"+className+moduleSuffix ;//接口名
		String modulePackagePath =tableConfig.modulePackagePath()+"."+moduleClassName;//接口所在包		
		String moduleFilePath =tableConfig.moduleFilePath()+"/"+ moduleClassName+ ".java";//生成接口文件地址
		String mapperXmlFilePath =tableConfig.mapperXmlFilePath()+"/"+ moduleClassName+"Mapper.xml";//生成xml文件地址		
		File moduleFile = new File(moduleFilePath);
		File mapperXmlFile = new File(mapperXmlFilePath);
		
		
		if (!moduleFile.exists()) {// 如果存在，则不重建
			//生成接口
			createModule(table,className,moduleClassName,tableConfig.modulePackagePath(),moduleFile);
		}
		if (!mapperXmlFile.exists()) {// 如果存在，则不重建
			//生成接口实现xml
			createMysqlMapperXml(table,className,modulePackagePath,mapperXmlFile,cols);
		}
	}
	
	
	/*  
	    * @Description:生成mapper接口的实现方法（复杂模式，包含动态数据源切换）
	    * 
	    * @param:													是否必须
	    * 
	    * table:表名	（t_user）												是
	    * pojoClass:表的pojo对象名（User）													是
	    * className:接口名（UserModule）												是
	    * packagePath:接口包路径	（com.module）										是
	    * classFile:接口文件													是
	    */
	private  void createModule(String table,String pojoClass,String className,String packagePath,File classFile) {
		try {
			StringBuilder sb = new StringBuilder();
			StringBuilder sbImport = new StringBuilder();
			sbImport.append("package " + packagePath + ";\n\n");
			String updateCacheHandle="";
			String queryCacheHandle="";
			if (tableConfig.useCache()) {
				updateCacheHandle="	 @CacheHandle(handle=SqlType.UPDATE)\n";
				queryCacheHandle="	 @CacheHandle\n";
				sbImport.append("import com.supers.annotation.CacheHandle;\n");
				sbImport.append("import com.supers.enums.SqlType;\n");
			}
			String usePojo="";
			if (tableConfig.usePojo()) {
				usePojo=pojoClass;
				sbImport.append("import "+tableConfig.pojoPackagePath()+"."+pojoClass+";\n");
			}else {
				usePojo="Map<String, Object>";
				sbImport.append("import java.util.Map;\n");
			}
			String pojoName=BeanUtil.lowerCaseFirst(pojoClass);
			classFile.createNewFile();
		
			sbImport.append("import java.util.List;\n");
			sbImport.append("import org.apache.ibatis.annotations.Param;\n");
			sbImport.append("import com.supers.enums.TableDml;\n");
			sbImport.append("import com.frames.datasource.DataSource;\n");
			sbImport.append("import com.frames.table.separator.IsInsert;\n");

			sbImport.append("\n\n");
			sb.append("public interface " + className + "{\n\n");
			
			//属性表名
			sb.append("	 String table=\""+table+"\";\n\n");
						
			//增删改查方法
			sb.append(updateCacheHandle);
			sb.append("	 @DataSource(write=true)\n");
			sb.append("	 @IsInsert(dml=TableDml.INSERT,tableName = \""+table+"\")\n");
			sb.append("	 int add"+pojoClass+"(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//添加数据\n\n");
			
			sb.append(updateCacheHandle);
			sb.append("	 @DataSource(write=true)\n");
			sb.append("	 @IsInsert(dml=TableDml.INSERT,tableName = \""+table+"\",batch=true)\n");
			sb.append("	 int batchAdd"+pojoClass+"(@Param(\""+pojoName+"s\")List<"+pojoClass+">"+" "+pojoName+"s);//批量添加数据\n\n");
			
			sb.append(updateCacheHandle);
			sb.append("	 @DataSource(write=true)\n");
			sb.append("	 @IsInsert(dml=TableDml.DELETE,tableName = \""+table+"\")\n");
			sb.append("	 int del"+pojoClass+"(@Param(\"tablenum\")int[] tablenum,@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//删除数据\n\n");
			
			sb.append(updateCacheHandle);
			sb.append("	 @DataSource(write=true)\n");
			sb.append("	 @IsInsert(dml=TableDml.DELETE,tableName = \""+table+"\",batch=true)\n");
			sb.append("	 int batchDel"+pojoClass+"ById(@Param(\"tablenum\")int[] tablenum,@Param(\"ids\")int[] ids);//根据id批量删除数据\n\n");
			
			sb.append(updateCacheHandle);
			sb.append("	 @DataSource(write=true)\n");
			sb.append("	 @IsInsert(dml=TableDml.UPDATE,tableName =\""+table+"\")\n");
			sb.append("	 int update"+pojoClass+"ById(@Param(\"tablenum\")int[] tablenum,@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//根据id修改数据\n\n");
			
			sb.append(updateCacheHandle);
			sb.append("	 @DataSource(write=true)\n");
			sb.append("	 @IsInsert(dml=TableDml.UPDATE,tableName = \""+table+"\")\n");
			sb.append("	 int update"+pojoClass+"ByCondition(@Param(\"tablenum\")int[] tablenum,@Param(\"cols\")"+pojoClass+" "+pojoName+"Cols,@Param(\"condtions\")"+pojoClass+" "+pojoName+");//根据条件修改数据,cols需要修改的列，condtions条件\n\n");
			
			sb.append(updateCacheHandle);
			sb.append("	 @DataSource(write=true)\n");
			sb.append("	 @IsInsert(dml=TableDml.UPDATE,tableName = \""+table+"\",batch=true)\n");
			sb.append("	 int batchUpdate"+pojoClass+"ById(@Param(\""+pojoName+"s\")List<"+pojoClass+">"+" "+pojoName+"s);//根据id批量更新数据\n\n");
			
			sb.append(queryCacheHandle);
			sb.append("	 int get"+pojoClass+"Count(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//获取数据总数\n\n");
			
			sb.append(queryCacheHandle);
			sb.append("	 "+usePojo+" get"+pojoClass+"(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//获取一条数据\n\n");
			
			sb.append(queryCacheHandle);
			sb.append("	 List<"+usePojo+"> get"+pojoClass+"List(@Param(\""+pojoName+"\")"+pojoClass+" "+pojoName+");//获取多条数据\n\n");
						
			sb.append("\n\n}\n\n");
			sbImport.append(sb);
			OutputStream os = new FileOutputStream(classFile);
			PrintStream ps = new PrintStream(os);
			ps.print(sbImport);
			os.flush();
			os.close();
			ps.flush();
			ps.close();
		}catch (IOException e) {
			e.printStackTrace();
		}		

	}
	
	
	
	
	
	
	/*  
	    * @Description:生成mapper.xml的实现方法（mysql数据库）（复杂模式，包含动态数据源切换）
	    * 
	    * @param:													是否必须
	    * 
	    * table:表名	（t_user）												是
	    * pojoClass:表的pojo对象名（User）													是
	    * mapperClassPackage:映射的接口包路径（com.module）												是
	    * classFile:xml文件										是
	    * cols:表的所有列													是
	    */
	private  void createMysqlMapperXml(String table,String pojoClass,String mapperClassPackage,File classFile,List<T2BVO> cols) {
		try {
			classFile.createNewFile();
			String pojoName=BeanUtil.lowerCaseFirst(pojoClass);
			StringBuilder sb = new StringBuilder();
			sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
			sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
			sb.append("<mapper namespace=\""+mapperClassPackage+"\" >\n\n");
			String id="";//表主键
			String pojoId="";//pojo对象的主键
			String usePojo="";
			if (tableConfig.usePojo()) {
				usePojo=tableConfig.pojoPackagePath().replace("/", ".")+"."+pojoClass;;
			}else {
				usePojo="map";
			}
			for (T2BVO vo : cols) {
				String colKey = vo.getColKey();
				String colName =vo.getColName();//表列名
				if (colKey.equalsIgnoreCase("PRI")) {
					id=colName;
					pojoId=BeanUtil.columnToField(id.toLowerCase());
					break;
				}

			}		
			
						

			sb.append("	<!-- 添加数据 -->\n");
			sb.append("	<insert id=\"add"+pojoClass+"\"  useGeneratedKeys=\"true\" keyProperty=\""+pojoName+"."+pojoId+"\">\n");
			sb.append("		INSERT INTO ${@com.frames.table.separator.CheckTableSize@getLastTable('"+table+"')} (\n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColByParam("+pojoName+")}\n");
			sb.append("		) VALUES(\n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getValByParam("+pojoName+",'"+pojoName+"')}\n");
			sb.append("		) ON DUPLICATE KEY UPDATE update_date=#{"+pojoName+".createDate} \n");
			sb.append("	</insert> \n\n");
			
			sb.append("	<!-- 批量添加数据 -->\n");
			sb.append("	<insert id=\"batchAdd"+pojoClass+"\">\n");
			sb.append("		<foreach collection=\""+pojoName+"s\" index=\"index\" item=\"item\"  separator=\";\">\n  ");
			sb.append("		INSERT INTO "+table+" (\n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColByParam(item)}\n");
			sb.append("		) VALUES(\n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getValByParam(item,'item')}\n");
			sb.append("		) ON DUPLICATE KEY UPDATE update_date=#{item.createDate}\n");
			sb.append("		</foreach>\n");
			sb.append("	</insert> \n\n");
			
			sb.append("	<!-- 删除数据 -->\n");
			sb.append("	<delete id=\"del"+pojoClass+"\" >\n");
			sb.append("		<foreach collection=\"tablenum\" index=\"index\" item=\"item\" separator=\";\">\n  ");
			sb.append("		delete from <if test=\"index==0 \">"+table+"</if><if test=\"index!=0 \">"+table+"_${index}</if>  \n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam("+pojoName+",'"+pojoName+"')}\n");
			sb.append("		</foreach>\n");
			sb.append("	</delete>  \n\n");
			

			sb.append("	<!-- 根据id批量删除数据 -->\n");
			sb.append("	<delete id=\"batchDel"+pojoClass+"ById\" >\n");
			sb.append("		<foreach collection=\"tablenum\" index=\"index\" item=\"item\" separator=\";\">\n  ");
			sb.append("		delete from <if test=\"index==0 \">"+table+"</if><if test=\"index!=0 \">"+table+"_${index}</if> where "+id+" in \n");			
			sb.append("		<foreach collection=\"ids\" index=\"index\" item=\"item\" open=\"(\" close=\")\" separator=\",\">\n  ");
			sb.append("			#{item}\n");
			sb.append("		</foreach>\n");
			sb.append("		</foreach>\n");
			sb.append("	</delete>  \n\n");
			
			sb.append("	<!-- 根据id修改数据-->\n");
			sb.append("	<update id=\"update"+pojoClass+"ById\"  >\n");
			sb.append("		<foreach collection=\"tablenum\" index=\"index\" item=\"item\" separator=\";\">\n  ");
			sb.append("		update <if test=\"index==0 \">"+table+"</if><if test=\"index!=0 \">"+table+"_${index}</if> set  \n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColVal("+pojoName+",'"+pojoName+"','"+pojoId+"')}\n");
			sb.append("		where "+id+"=#{"+pojoName+"."+pojoId+"} \n");
			sb.append("		</foreach>\n");
			sb.append("	</update>  \n\n");
			
			sb.append("	<!-- 根据条件修改数据,cols需要修改的列，condtions条件-->\n");
			sb.append("	<update id=\"update"+pojoClass+"ByCondition\"  >\n");
			sb.append("		<foreach collection=\"tablenum\" index=\"index\" item=\"item\" separator=\";\">\n  ");
			sb.append("		update <if test=\"index==0 \">"+table+"</if><if test=\"index!=0 \">"+table+"_${index}</if> set  \n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColVal(cols,'cols','')}\n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam(condtions,'condtions')}\n");
			sb.append("		</foreach>\n");
			sb.append("	</update>  \n\n");
			
			sb.append("	<!-- 根据id批量更新数据-->\n");
			sb.append("	<update id=\"batchUpdate"+pojoClass+"ById\">\n");
			sb.append("		<foreach collection=\""+pojoName+"s\" index=\"index\" item=\"item\"  separator=\";\">\n  ");
			sb.append("		update "+table+" set  \n");			
			sb.append("			${@com.frames.table.NewBeanTableUtil@getColVal(item,'item','"+pojoId+"')}\n");
			sb.append("		where "+id+"=#{item."+pojoId+"} \n");
			sb.append("		</foreach>\n");
			sb.append("	</update> \n\n");
			
			sb.append("	<!-- 获取数据总数-->\n");
			sb.append("	<select id=\"get"+pojoClass+"Count\" resultType=\"int\">\n");
			sb.append("		SELECT count(1) FROM "+table+" \n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam("+pojoName+",'"+pojoName+"')}\n");
			sb.append("	</select>  \n\n");
			
			sb.append("	<!-- 获取一条数据-->\n");
			sb.append("	<select id=\"get"+pojoClass+"\" resultType=\""+usePojo+"\">\n");
			sb.append("		SELECT ${"+pojoName+".selectCols} FROM ${@com.frames.table.separator.CheckTableSize@getQueryTable('"+table+"')} \n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam("+pojoName+",'"+pojoName+"')}\n");
			sb.append("	</select>  \n\n");
			
			sb.append("	<!-- 获取多条数据-->\n");
			sb.append("	<select id=\"get"+pojoClass+"List\"  resultType=\""+usePojo+"\">\n");
			sb.append("		SELECT ${"+pojoName+".selectCols} FROM ${@com.frames.table.separator.CheckTableSize@getQueryTable('"+table+"')} \n");
			sb.append("			${@com.frames.table.NewBeanTableUtil@getCondtionByParam("+pojoName+",'"+pojoName+"')}\n");
			sb.append("		${"+pojoName+".orderLimit} \n");
			sb.append("	</select>  \n\n");
			

			
			sb.append("</mapper>");
			OutputStream os = new FileOutputStream(classFile);
			PrintStream ps = new PrintStream(os);
			ps.print(sb);
			os.flush();
			os.close();
			ps.flush();
			ps.close();
		}catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	

}
